package com.yuedou.api.pay.nongshang;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yuedou.api.entity.platform.PlatformPay;
import com.yuedou.api.entity.platform.SplitAccount;
import com.yuedou.api.util.DateUtil;
import com.yuedou.api.util.OkHttpClientUtil;
import com.yuedou.api.util.StringUtil;
import okhttp3.Response;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

import javax.crypto.Cipher;

public abstract class DaiPayUtil {

	public final static String ALGORITHM_SHA256WITHRSA = "SHA256withRSA";

	public static final String KEY_ALGORITHM = "RSA";

	private static char[] HEXCHAR = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };


	/**
	 *  单笔代付接口
	 * @param platformPay
	 * @param orderNo
	 * @param splitAccount
	 * @param payMoney
	 * @param remark
	 * @return
	 */
	public static JSONObject payApi(PlatformPay platformPay, String orderNo, SplitAccount splitAccount, Double payMoney, String remark){
		JSONObject req = null;
		Map<String,String> content = new HashMap<>();
		content.put("sysId",platformPay.getSysId());
		content.put("sysOrderId",orderNo);//系统订单号  外部平台需保证各自系统上传的该字段的唯一性
		content.put("mchntNo",platformPay.getMerNo());//用于付款的商户编号
//		content.put("responseUrl",platformPay.getSysId());//平台用于接收代付结果通知的URL  可空
		//时间戳  请求时间yyyyMMddHHmmss，与当前时间差不能超过5分钟  20171129125300
		content.put("timestamp", DateUtil.getSdfTimes());
		content.put("revAcctName", splitAccount.getRealName());//收款人姓名
		content.put("revAcctNo",splitAccount.getCardNum());//收款账号
		//代付金额  单位分，此处金额不得大于查询可代付金额接口返回的字段
		content.put("payAmt", StringUtil.yuanToCent(String.valueOf(payMoney)));
		content.put("revIdCardNum",splitAccount.getIdNo());//收款人身份证号
		content.put("remark", remark);//备注
		content.put("verify", "false");//是否需要实名验证
//		content.set("mobilePhone",platformPay.getSysId());//收款人手机号
//		//8位长度，如果传了终端号，就要和实际录入的对应，否则校验不通过，不塞则默认12345678
//		content.set("termNo",platformPay.getSysId());
		String ss = generateSortString(content,true);
		String sign = "";
		try {
			System.out.println("计算签名的数据： " + ss);
			sign = sign(ss.getBytes(), platformPay.getPrivateKey(),ALGORITHM_SHA256WITHRSA);
			System.out.println("签名后的数据： " + sign);
			content.put("sign",sign);//签名
		} catch (Exception e) {
			e.printStackTrace();
		}

		if(StrUtil.isEmpty(sign)){
			req = new JSONObject();
			req.set("code","sign_fail");
			return req;
		}

		try {
			JSONObject jsonObject = JSONUtil.parseObj(content);
			String reqJson = jsonObject.toString();
			System.out.println("content 明文： " + reqJson);
			String messageEn = toHexString(encryptByPublicKey(reqJson.getBytes(), platformPay.getPayPublicKey(), 245));
			System.out.println("content 密文： " + messageEn);

			String url = "https://managefree.chinaums.com/uisouterfront/singlepayment/process";
//			url="https://mobl-test.chinaums.com/uisouterfront/singlepayment/process";

			JSONObject requestBody = new JSONObject();
			requestBody.set("content",messageEn);
			requestBody.set("appSource",platformPay.getSysId());
			requestBody.set("msgSrc","API");
			requestBody.set("msgType","/singlepayment/process");
			Map<String,Object> map = new HashMap<>();
			map.put("content",messageEn);
			map.put("appSource",platformPay.getSysId());
			map.put("msgSrc","API");
			map.put("msgType","/singlepayment/process");


			String requestBodyStr = requestBody.toString();
			System.out.println("最终请求报文体: " + requestBodyStr);
			Response response = OkHttpClientUtil.getInstance().postData(url,map);
			System.out.println("代付响应数据" + response.body().string());
			String responseData = response.body().string();
//			64fe7de3afcda16648960e373f32dbcccfe582ee9e4b777f6c51beeb027d0f8d6fb5410aac4af0527321cd0934662b3da0ca5bebdb88f7c4da45ef47b1b3bf78d7334fcf4aad330fb66fedfabd7d41fd9a6dd782bc584c812a64f7fec04aa12968a2d2a0e394231428c03f8bdbe9cc5d1d011746080211c9ea627588bcacbd2897992a4ed0cda08f89ad53a6f9d3d60ea4c5680343e03a6b9fa621890f60e51b0063332fc5f7dd8bbf95382962b51c38c2a0a2a0f75ee1f3417db3b1edff1e9889046d974a435bc5193aaeb9ea211e5f0de7e05e0f1d0c9237cbd526900949b1b9a08c69a5c5c84c8e82764826695dfb38670fe8206474c37b16c3f3431a12d70dddb18d0eb46c933c1afaf7edf1db97246c0a66b49d156e6d3c2e1809f46d5cba1bd6b7c7ae8ff323412857f422f6859b8756a6fac220f30fa284eda7a2a09a2729ec647ec6c078364887a280a1d7db4f9c47c1da714a12c5d7b9abcc9ca7824c142e53523e04cf27584395b1304ccb466b2501a7ed711979be9dc347073c8f1f246effc821fa952868d34585fb1a1f54407d58008301b9a5a53d0945f2f091859db89d09ea4b1d9ace1ed9d70bb7869a0903ec516f8172b22b269a0af589c4dd75bcb88332ea1434476aff893d9c722be1cacbc1c27e478e87ac53f1dc18d3a29d90f690748ccd052eec8c73306273049fdfbfcccafa0991dfd81d54691e021d7fc278defbdc39c2713aeb3e867102fad5d107f34532b8dbb40fd676b8e6b8ff9c8cb8f551dae1c19878d7962a66e0ef1eb1d623ecb881e34269a386c436c99c7c5ba7ed73f7596aab18964c156b64e531e7d4ba0b06eecaf1779e48ccc3ca4548526fa2ebeb6b742ccb3ea9a2ab5c00735f81018d8a5be544848500ec585b7b025d32e858f9de72961c9e728ef4ee161a6cafdb70a9bc29b5be1062e55a4de862f2be59614457e3a7a96dec996af15a15d612f4fe967f858387e5f20ac53f6188d136af7c320648c0bbd567ff004b256189c29f88a751eb9f6d101d9a80668f1c5e2277c5e3110d6fafb07f3821b129305ec6a318a5077bd075a4df327dc0


			//分段解密（用外部平台私钥）
			byte[] decryptByte = decryptByPrivateKey(toBytes(responseData), platformPay.getPrivateKey(),256);
			Map<String,String> contentMap = JSONUtil.toBean(new String(decryptByte, "UTF-8"), Map.class);
			byte[] data = generateSortString(contentMap, true).getBytes("UTF-8");
			//true-验签成功
			boolean isVerified = verify(data, platformPay.getPayPublicKey(), contentMap.get("sign"), ALGORITHM_SHA256WITHRSA);
			System.out.println("contentMap: " + contentMap);
			System.out.println("isVerified: " + isVerified);
			if(isVerified){
				//验证通过
				JSONObject responseJson = JSONUtil.parseObj(contentMap);
				return responseJson;
			}else{
				req = new JSONObject();
				req.set("code","validate_sign_fail");
				return req;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return req;
	}


	/**
	 * 组装签名排好顺序的字段
	 * @param map
	 * @param allowValueNull 允许map的值为空，true允许；若允许为空会出现a=&b=
	 * @return
	 */
	public static String generateSortString(Map<String, String> map, boolean allowValueNull) {
		List<String> keys = new ArrayList<String>(map.size());
		for (String key : map.keySet()) {
			if ((!allowValueNull && isEmpty(map.get(key))) || "sign".equals(key)
					|| "signValue".equals(key)) {
				continue;
			}
			keys.add(key);
		}
		Collections.sort(keys);
		StringBuffer sb = new StringBuffer();
		boolean isFirst = true;
		for (String key : keys) {
			if (isFirst) {
				sb.append(key).append("=").append(map.get(key));
				isFirst = false;
				continue;
			}
			sb.append("&").append(key).append("=").append(map.get(key));
		}
		return sb.toString();
	}

	/**
	 * 签名
	 * @param rawData 签名裸数据
	 * @param privateKey 私钥
	 * @param algorithm  签名验签算法
	 * @return
	 * @throws Exception
	 * @throws
	 */
	public static String sign(byte[] rawData, String privateKey, String algorithm) throws Exception {
		byte[] keyBytes = decryptBASE64(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
		Signature instance = Signature.getInstance(algorithm);
		instance.initSign(priKey);
		instance.update(rawData);
		return toHexString(instance.sign());
	}

	/**
	 * 验证签名.
     * @param data
     * @param publicKey
     * @param sign
	 * @param algorithm
	 * @return
	 * @throws Exception
	 */
     public static boolean verify(byte[] data, String publicKey, String sign,String algorithm) throws Exception {
         byte[] keyBytes = decryptBASE64(publicKey);
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
         PublicKey pubKey = keyFactory.generatePublic(keySpec);
         Signature signature = Signature.getInstance(algorithm);
         signature.initVerify(pubKey);
         signature.update(data);
         return signature.verify(toBytes(sign));
     }

	/**
	 * 公钥分段加密
	 * @param data 源数据
	 * @param publicKey 公钥(BASE64编码)
	 * @param length 段长 1024长度的公钥最大取 117
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(byte[] data, String publicKey, int length) throws Exception {
		byte[] keyBytes = decryptBASE64(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > length) {
				cache = cipher.doFinal(data, offSet, length);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * length;
		}
		byte[] encryptData = out.toByteArray();
		out.close();
		return encryptData;
	}


	/**
	 * * <P>
     * 私钥解密
     * </p>
     *
     * @param data 已加密数据
     * @param privateKey 私钥(BASE64编码)
	 * @param length 分段解密长度  128
	 * @return
	 * @throws Exception
	 */
    public static byte[] decryptByPrivateKey(byte[] data, String privateKey,int length) throws Exception {
        byte[] keyBytes =  decryptBASE64(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > length) {
                cache = cipher.doFinal(data, offSet, length);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * length;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

	/**
	 * base64解码
	 * @param src
	 * @return
	 */
	public static byte[] decryptBASE64(String src) {
		sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
		try {
			return decoder.decodeBuffer(src);
		} catch (Exception ex) {
			return null;
		}
	}
	/**
	 * base64编码
	 * @param src
	 * @return
	 */
	public static String encryptBASE64(byte[] src) {
		sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
		return encoder.encode(src);
	}

	/**
	 * 从byte数组转16进制字符串
	 * @param b
	 * @return
	 */
	public static String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            sb.append(HEXCHAR[(b[i] & 0xf0) >>> 4]);
            sb.append(HEXCHAR[b[i] & 0x0f]);
        }
        return sb.toString();
    }

	/**
	 * 从16进制字符串转byte数组
	 * @param s
	 * @return
	 */
	public static final byte[] toBytes(String s) {
        byte[] bytes;
        bytes = new byte[s.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
                    16);
        }
        return bytes;
    }

	public static boolean isEmpty(Object str) {
		return (str == null || "".equals(str));
	}

	public static void main(String[] args) throws Exception {
//		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmxuPyNHXhXYB8QGALvvGmJugtxKo+YWL2mgWrnpM3GWSmET4q99XIELeTKN3rvLxHdJdFbm/1jSOKwey5CMklPoR0R+mZkvuoyIE8QXv880YGoetMf1DFKIzjtMe31rVKzNvOueJtNPHo43B8/SQXtiOyTPTres+p8h6cQmitIQIDAQAB";
//		String privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbG4/I0deFdgHxAYAu+8aYm6C3Eqj5hYvaaBauekzcZZKYRPir31cgQt5Mo3eu8vEd0l0Vub/WNI4rB7LkIySU+hHRH6ZmS+6jIgTxBe/zzRgah60x/UMUojOO0x7fWtUrM28654m008ejjcHz9JBe2I7JM9Ot6z6nyHpxCaK0hAgMBAAECgYBxnddWfsS71n4cp6KG/fsULTdJTsyIGMJZq44nX619APCfbenDTfm3BSR6vYGKApbluxj+9QCS8ScAdaJ2X/TfMBGXENJt3IxZYYxdkrBTIVqwNrxw5NugRI9UEiVhK7K1cJi+yoWz97cUvxz4wSjdETMkW7/wwKz1IenM8EqcHQJBAM+Y+Wi1kTerfx97M6qA+jfFwpA6rtIjvheVfzIB8QWPzeuNzYFBa8+Ap3cm4DKU6smL+1zlWKmvUkA4EkGjXFcCQQDNqWzPYXPSK1WiRUEl+OhKJ6ykFVD0olSR5QveRWNFVpYMznbQySa0QocSOLijz96SDbzCG5+K5NN78ILYu9dHAkA61SKRryspeLu9I0BAKO9AkRYTo93ZhfGgY2i5tl0k810rTXOZFv5DvzU2iljtXNCxL6+b4w9ef2Yy9vENkwtfAkEAwKeFln7j0G1nuqrFbJzOfSjNQKf3PjMSpdi6VW0KoVmLFlQSWWMVLqdjgF5CGLIQ/SCBQhQ+UA4rTl7vM7hC4QJAWCvn/p32/W1WfLnS8W5peMOgNICbZ491wJtcUc3GGO/wpfK/Lh7L7cyfB4oK+Cz6ISlcHSDyhzbdNfAP47Hddw==";
//
//		String str = "234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890234567890-234567890234567890-1234567890234567890";
//		//公钥加密
//		byte[] encryptData = encryptByPublicKey(str.getBytes(), publicKey, 117);
//
//		//私钥解密
//		byte[] data = decryptByPrivateKey(encryptData, privateKey, 128);
//
//		System.out.println(new String(data));
//
//
//		byte[] rowData = str.getBytes();//待签名数据
//		String signStr = sign(rowData, privateKey, ALGORITHM_SHA256WITHRSA);
//		System.out.println(signStr);//签名结果数据（16进制字符串）
//		//验证签名
//		System.out.println(verify(rowData, publicKey, signStr, ALGORITHM_SHA256WITHRSA));
//



		String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCDeoZARtucaqMoTZlpAIoWsNcDWRzjBcM2UP9mOZjy64pW0HvOYcUXepTJ+gdFP5/dBPtKz7pvRU/drLN5NoBAYsFCWXhWjQYcizsVGzTZ20ULKylSP7MuqSb12/NRUfA1Fk+6HPksGPWt8BPqU1ZvmQkEVIo8Y7ia9y1d3Uc0irECIgwfVFN4Zeck2xFyc/4NUqsp4Ia4cSpf5f3uqwkfzEXIMTKSlvD+RHui8tRPjf4wZIBnoCY03lwhjT8Veu+qDw2bNzYdY5hAEIFTPeWYGHnJZQDIcXAcaOg2ALkPpCmXym7Eo14Xl2JAjqilWyvAA2WC7OJ5F93sfzL/gvL7AgMBAAECggEAJEid4AMt+/6ZxDeWDJovgY+P5sai6Cvg8Y5szSM8CF3kMY0bfZsRrycPBKZRd1TVo0MKrlyhUK/KGJzecqcNwbb/KnZSdWA5vYrW5T462Zxfc3OX1bDqnAfmTpdCkMCSD7R2kCAKy5afxj6o4FPbWLTc/iruczf57BomlO7KBb+RW1eBofD7fD6F7oYvISKSe8TZ/ZFHqKFPAf3t8kF21N2FQ3+mbOAWBngA1pQGTbyrG+oA/zMfDf6oezJdkSzrlGgW1PyZrm9h8l1ECTg+fuAmVR2WBypmvCYQDayvneKtKETXrG9k3uaNXqjRbQiATixUW5LllmPrsx5E1r0ZcQKBgQDfXzvLf5zqXwOGxyFdVnjgpluhf18fyM9gO/Tf7TIpKR5ZLoKF5dBDZ/mHK2iXpI/6hz8pl3LUdjidyaDJ2qXDXpSKkjKdM0Qcduf7p+f1BNLheFsqWmFlRdvWEHvNJiN0XBbIQ1+oP+fXsBYFdocMY9ZXpmKUzcogUNXla/m9XQKBgQCWrwgnLocRCkudBJQAKEy1E/jL3HQF1jmWryc3ibuOULKX6cGOzSBSDj0JYRQeWiffIjVgpdMmpG/ryCEaKmgPCFy2iu/WVLEoP7pzSiyygXTMMHvoT4oObPJNO0dNbd9Ur3yBQqEj9gqUbVY9lVZTaT7wI2FhU2kdR0WnwVAUNwKBgQCISEFiMlTZhejP5VSM7wJHBhin2t99s/YaX9pSeRR+mnDCtqa57PH4/kn211w0ERorHzNBO/66c/qtAmSQY095eI4mUXaCBNJMj5uQJexWyH+lQtpUZ9o+gLXU0C/Ihblh+AGKY9jL/VmFdhCpepyAybTvuzswULI+rzMhi5ROnQKBgCncCenIlSD4uTSvduXsTBLpr24CmgCdGHZxxfU5v+6zIEnvWCPxfA8PgYk/fLVJ2lW0TRvCNTxA5g6cFAYOzcWPTyIuyp3B/UzvFz671lrod6fZuDI7FmEXhuBJnW83HJmL/oxyFA3HZf0Burl06PxW+nL/gSfmYgcOK52EqFhVAoGBAIhi8MsRG/rE8P9l4rjrnjoykDmEutuXCEZkwRBhvfXXr/vY0MyKzFtKvc4zXSSNfm27t5+2UQho429F7JPngx6G6rojA+6uqWTdIlsWXSq4OSuzIMHVR3AbOoNcLqsF8J4G5uGtOFDqnXuwYYxz6Yz69t/ysxP5X2QuefTztIsW";

		String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhTzN8wxdXYr+/+t8iX0mlol8wFy+0pGtxnyB6PjyrIRjGHrZJA7grZPvy7MOK6PqihqTZh6SO7tX9StxVmTQo+PuibAY/p2i08UxkIBUcucHVvHN8gkM3GBFBqD0uJgUc03cerEI7gNeaKYfCVs0/hMo6CKbdXVKqaE987kXYK209uFcte+Y8YofQ2AYamImpzSf7pXomAu+8D98HIOs5bKITHTk30vPdNhrQdpDRO1TuX0x8bwhCykcwAEdB/Z9YGXkLU5S3QJY2qvCZJY08YdNqIpbDqifSRvOg0sqeKFXPfI2M0GsOh6PArTEmh0QHxDht9xjPPt11aVgh8kgkQIDAQAB";

		String req = "64fe7de3afcda16648960e373f32dbcccfe582ee9e4b777f6c51beeb027d0f8d6fb5410aac4af0527321cd0934662b3da0ca5bebdb88f7c4da45ef47b1b3bf78d7334fcf4aad330fb66fedfabd7d41fd9a6dd782bc584c812a64f7fec04aa12968a2d2a0e394231428c03f8bdbe9cc5d1d011746080211c9ea627588bcacbd2897992a4ed0cda08f89ad53a6f9d3d60ea4c5680343e03a6b9fa621890f60e51b0063332fc5f7dd8bbf95382962b51c38c2a0a2a0f75ee1f3417db3b1edff1e9889046d974a435bc5193aaeb9ea211e5f0de7e05e0f1d0c9237cbd526900949b1b9a08c69a5c5c84c8e82764826695dfb38670fe8206474c37b16c3f3431a12d70dddb18d0eb46c933c1afaf7edf1db97246c0a66b49d156e6d3c2e1809f46d5cba1bd6b7c7ae8ff323412857f422f6859b8756a6fac220f30fa284eda7a2a09a2729ec647ec6c078364887a280a1d7db4f9c47c1da714a12c5d7b9abcc9ca7824c142e53523e04cf27584395b1304ccb466b2501a7ed711979be9dc347073c8f1f246effc821fa952868d34585fb1a1f54407d58008301b9a5a53d0945f2f091859db89d09ea4b1d9ace1ed9d70bb7869a0903ec516f8172b22b269a0af589c4dd75bcb88332ea1434476aff893d9c722be1cacbc1c27e478e87ac53f1dc18d3a29d90f690748ccd052eec8c73306273049fdfbfcccafa0991dfd81d54691e021d7fc278defbdc39c2713aeb3e867102fad5d107f34532b8dbb40fd676b8e6b8ff9c8cb8f551dae1c19878d7962a66e0ef1eb1d623ecb881e34269a386c436c99c7c5ba7ed73f7596aab18964c156b64e531e7d4ba0b06eecaf1779e48ccc3ca4548526fa2ebeb6b742ccb3ea9a2ab5c00735f81018d8a5be544848500ec585b7b025d32e858f9de72961c9e728ef4ee161a6cafdb70a9bc29b5be1062e55a4de862f2be59614457e3a7a96dec996af15a15d612f4fe967f858387e5f20ac53f6188d136af7c320648c0bbd567ff004b256189c29f88a751eb9f6d101d9a80668f1c5e2277c5e3110d6fafb07f3821b129305ec6a318a5077bd075a4df327dc0";


		//分段解密（用外部平台私钥）
		byte[] decryptByte = decryptByPrivateKey(toBytes(req), privateKey,256);
		Map<String,String> contentMap = JSONUtil.toBean(new String(decryptByte, "UTF-8"), Map.class);
		byte[] data = generateSortString(contentMap, true).getBytes("UTF-8");
		//true-验签成功
		boolean isVerified = verify(data, publicKey, contentMap.get("sign"), ALGORITHM_SHA256WITHRSA);
		System.out.println("contentMap: " + contentMap);
		System.out.println("isVerified: " + isVerified);


		//{refNo=, responseDesc=商户代付信息查找失败或未开通代付, sysId=10160, transId=,
		// sign=2edfa4ebf6142b8df03c02155d9678f508da6dad4d916b7a3c1fb969a8db12520a16fd3ac11e91962e1f4b34b3d02b303160eb
		// 1cedc8f43ffc3cd1f5f3f099173aa5eeef79b1074853ada9a7bb91f3d5997a9e48168ef26bb52d0ae8f76d8e1b9d80fcfa9ca951d89
		// 1b58af36605a35681a6cd09e98f49c23cfef227effd39379559270321f158552e495fed1c18880ab5881c951da563a4e50302e92108
		// 61276e24e0f329511637b6016458b4d2680ae8d38c9cde8d44ce10bb6f2b5249862b479b85cc0b5a9bf08fe47f33fbdf0c6411c9920
		// 84c371090d43b3a791eca12ef2d342e71ee59fb9cbb5cc8884b8775c64000f353b57c8e24b935ab636e5a2e57,
		// sysOrderId=, responseCode=999999, ssn=, desc=, status=}





	}
}
